#include "adc.h"

#include "main.h"
#include "c8051F320.h"
#include "usb_command.h"
#include "USB_API.h"

#define MEASURE_BUFFER_SIZE 256

unsigned xdata adc_measure_buffer[ADC_BUFFER_SIZE];
unsigned adc_buffer_first;
unsigned adc_buffer_last;

void init_adc ()
{
	adc_buffer_first = 0;
	adc_buffer_last = 0;

	EIE1 &= ~0x80; // desactivo interrupcion de timer 3
	/* regreso controles de timer 3 a condiciones de reinicio, pero contando SYSCLK */
	TMR3CN = 0x00;
	CKCON = 0x40;

	TMR3RLL = (65535 - (unsigned)(SYSCLK/1000)) % (0x01<<8);
	TMR3RLH = (65535 - (unsigned)(SYSCLK/1000)) / (0x01<<8);

	//AD0TM = 1; // modo de consumo/velocidad baja
	/* valores a usar para medir */
	AMX0P = ADC_P1_0;
	AMX0N = ADC_GND;
	ADC0CN = (ADC0CN & ~0x07) | 0x05; // convierte por overflow de timer 3
}

void adc_start ()
{
	/* timer 3 hace overflow inmediato */
	//TMR3L = 0xFF;
	//TMR3H = 0xFF;
	EIE1 |= 0x08; //activo interrupcion ADC
	TMR3CN |= 0x04; // activo timer 3
	AD0EN = 1; // activo ADC
}

void adc_stop ()
{
	EIE1 &= ~0x08; //activo interrupcion ADC
	TMR3CN &= ~0x04; // desactivo timer 3
	AD0EN = 0; // desactivo ADC
}

void ADC_conversion_complete_ISR () interrupt INTERRUPT_ADC0_EOC
{
	unsigned candidate_next;
	unsigned temp;

	AD0INT = 0;

	candidate_next = (adc_buffer_last + 1) % ADC_BUFFER_SIZE;
	if (candidate_next == adc_buffer_first) {
		// drop
		return;
	}

	temp = ADC0H;
	temp <<= 8;
	temp += ADC0L;
	adc_measure_buffer[adc_buffer_last] = temp;
	adc_buffer_last = candidate_next;
}
